/*
 * Copyright (C) 2008 GeoScheduler Team, as stated on <http://www.geoscheduler.org/authors>.
 * 
 * This file is part of GeoScheduler.
 * 
 * GeoScheduler is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GeoScheduler is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with GeoScheduler. If not, see <http://www.gnu.org/licenses/>.
 */
package org.geoscheduler.dao.ibatis;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.geoscheduler.dao.EventDAO;
import org.geoscheduler.model.Event;
import org.geoscheduler.model.dto.EventQueryDTO;
import org.springframework.dao.DataAccessException;
import org.springframework.transaction.annotation.Transactional;

/**
 * FIXME [lko] comment me!
 * 
 * @author lko
 */
public class SqlMapEventDAO extends SqlMapAbstractDAO implements EventDAO {

	@Transactional
	public int delete(Long id) throws DataAccessException {
		return getSqlMapClientTemplate().delete("deleteEvent", id);
	}
	
	@Transactional
	public int deleteByIdAccount(Long accountId) throws DataAccessException {
		return getSqlMapClientTemplate().delete("deleteEventsByAccountId", accountId);
	}

	@Transactional
	public boolean isOwnedByIdAccount(Long eventId, Long accountId) throws DataAccessException {
		Map<String, Object> params = new HashMap<String, Object>(2);
		params.put("eventId", eventId);
		params.put("accountId", accountId);
		return Boolean.TRUE.equals(getSqlMapClientTemplate().queryForObject("isOwnedByIdAccount", params));
	}

	@Transactional
	public Event insert(Event event) throws DataAccessException {
		Long id = (Long) getSqlMapClientTemplate().insert("insertEvent", event);
		event.setId(id);
		event.setVersion(0);
		return event;
	}

	@Transactional(readOnly = true)
	public Event loadById(Long id) throws DataAccessException {
		return (Event)getSqlMapClientTemplate().queryForObject("selectEventById", id);
	}

	@Transactional
	public Event update(Event event) throws DataAccessException {
		if (getSqlMapClientTemplate().update("updateEvent", event) == 1) {
			updateVersion(event);
			return event;
		} else {
			return (Event)getSqlMapClientTemplate().queryForObject("selectEventById", event.getId());
		}
	}

	@Transactional(readOnly = true)
	@SuppressWarnings("unchecked")
	public List<Event> loadByIdAccount(Long id) throws DataAccessException {
		return getSqlMapClientTemplate().queryForList("selectEventsByIdAccount", id);
	}
	
	public List<Event> query(EventQueryDTO queryDTO) throws DataAccessException {
		if (queryDTO.getAccount() != null) {
			return queryPrivate(queryDTO);
		} else {
			return queryPublic(queryDTO);
		}
	}
	
	@Transactional(readOnly = true)
	@SuppressWarnings("unchecked")
	public List<Event> queryPrivate(EventQueryDTO queryDTO) throws DataAccessException {
		if ((queryDTO.getLat() == 0) || (queryDTO.getLon() == 0)) {
			// we don't have location
			if ((queryDTO.getTimeFrom() != null) || (queryDTO.getTimeTo() != null)) {
				// we have only time (no location)
				return getSqlMapClientTemplate().queryForList("allPrivateEventsWithTimeQuery", queryDTO);
			} else {
				// we have neither location nor time
				return getSqlMapClientTemplate().queryForList("allPrivateEventsQuery", queryDTO);
			}
		} else {
			// we have location
			if ((queryDTO.getTimeFrom() != null) || (queryDTO.getTimeTo() != null)) {
				// we have time location and time
				return getSqlMapClientTemplate().queryForList("privateEventsWithTimeQuery", queryDTO);
			} else {
				// we have only location
				return getSqlMapClientTemplate().queryForList("privateEventsQuery", queryDTO);
			}
		}
	}
	
	@Transactional(readOnly = true)
	@SuppressWarnings("unchecked")
	public List<Event> queryPublic(EventQueryDTO queryDTO) throws DataAccessException {
		if ((queryDTO.getLat() == 0) || (queryDTO.getLon() == 0)) {
			// we don't have location
			return Collections.EMPTY_LIST;
		} else {
			// we have location
			if ((queryDTO.getTimeFrom() != null) || (queryDTO.getTimeTo() != null)) {
				// we have time location and time
				return getSqlMapClientTemplate().queryForList("publicEventsWithTimeQuery", queryDTO);
			} else {
				// we have only location
				return getSqlMapClientTemplate().queryForList("publicEventsQuery", queryDTO);
			}
		}
	}

	@Transactional
	public int addTag(Long eventId, Long tagId) throws DataAccessException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eventId", eventId);
		params.put("tagId", tagId);
		return (getSqlMapClientTemplate().insert("insertEventTag", params) == null) ? 0 : 1;
	}

	@Transactional
	public int removeTag(Long eventId, Long tagId) throws DataAccessException {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eventId", eventId);
		params.put("tagId", tagId);
		return getSqlMapClientTemplate().delete("insertEventTag", params);

	}
}
